﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace SectorsDesigner
{
    public partial class SectorsDesignerMain : Form
    {
        public bool Freezed = false;
        public SectorsMapMakerControl dx;
        string AppTitle = "Sectors World Designer";
        public SectorsDesignerMain()
        {
            InitializeComponent();
            //Doing these by hand after "dx" got deleted by the annoying forms designer bug
            dx = new SectorsMapMakerControl();
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
            dx.SuspendLayout();
            this.splitContainer1.Panel1.SuspendLayout();
            dx.MouseClick += dx_MouseClick;
            dx.MouseMove += dx_MouseMove;
            dx.MouseDown += dx_MouseDown;
            dx.Resize += dx_Resize;
            dx.Dock = DockStyle.Fill;
            splitContainer1.Panel1.Controls.Add(dx);
            this.toolStripContainer1.ResumeLayout(false);
            dx.ResumeLayout(false);
            this.toolStripContainer1.PerformLayout();
            this.splitContainer1.Panel1.ResumeLayout(false);
            this.splitContainer1.Panel1.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
            dx.Show();

            Application.Idle += delegate { Update(); };
            dx.SectorsListBox = sectorsListBox;
            dx.EdgesListBox = wallsListBox;
            dx.VerticesListBox = verticesListBox;
            dx.TreeView = treeView1;
            dx.AfterRefresh = RefreshToolbar;
            dx.BeforeRefresh = BeforeRefresh;
        }

        bool locked = false;
        void BeforeRefresh()
        {
            locked = true;
        }

        private void dx_MouseMove(object sender, MouseEventArgs e)
        {
            dx.MousePosition = new Microsoft.Xna.Framework.Vector2(e.X, e.Y);
            dx.MouseButton = e.Button;
        }

        public new void Update()
        {
            if (!Freezed) dx.Invalidate();
        }

        private void dx_MouseClick(object sender, MouseEventArgs e)
        {
            try
            {
                dx.MouseClicked(e);
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void dx_MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                dx.MouseDowned(e);
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
        }

        private void dx_Resize(object sender, EventArgs e)
        {
            dx.Resized(e);
        }

        private void newWorldToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                dx.New();
                dx.RefreshListBox();
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            Text = AppTitle;
        }

        private void openWorldToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                var d = new OpenFileDialog();
                d.ShowDialog();
                dx.Open(d.FileName);
                dx.FileName = d.FileName;
                Text = AppTitle + " - " + new FileInfo(dx.FileName).Name;
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                var d = new SaveFileDialog();
                d.ShowDialog();
                dx.Save(d.FileName);
                dx.FileName = d.FileName;
                Text = AppTitle + " - " + new FileInfo(dx.FileName).Name;
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void btnNewSector_Click(object sender, EventArgs e)
        {
            dx.EditMode = SectorsMapMakerControl.EditModes.NewSector;
            RefreshToolbar();
        }

        private void btnSelectLine_Click(object sender, EventArgs e)
        {
            dx.EditMode = SectorsMapMakerControl.EditModes.SelectEdge;
            RefreshToolbar();
        }

        private void btnSelectSector_Click(object sender, EventArgs e)
        {
            dx.EditMode = SectorsMapMakerControl.EditModes.SelectSector;
            RefreshToolbar();
        }

        private void btnMoveVertex_Click(object sender, EventArgs e)
        {
            dx.EditMode = SectorsMapMakerControl.EditModes.SelectVertex;
            RefreshToolbar();
        }

        private void btnProperties_Click(object sender, EventArgs e)
        {
            try
            {
                new SectorPropertiesForm(dx.Sectors[dx.CurrentSectorIndex],dx).ShowDialog();
                dx.RefreshListBox();
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void sectorsListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (locked) return;
            try
            {
                dx.EditMode = SectorsMapMakerControl.EditModes.SelectSector;
                dx.SelectedSectorsIndices = new List<int>();
                foreach (int item in sectorsListBox.SelectedIndices)
                {
                    dx.SelectedSectorsIndices.Add(item);
                }
                //dx.CurrentSectorIndex = sectorsListBox.SelectedIndex;
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            try
            {
                if (MessageBox.Show("Are you sure you want to delete these sectors?", "Remove Sectors", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No) return;
                dx.RemoveSectors();
                dx.RefreshListBox();
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void scriptAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                var d = new SaveFileDialog();
                d.ShowDialog();
                File.WriteAllLines(d.FileName, ScriptHelper.Script(dx).Split('\n'), Encoding.ASCII);
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }



        private void btnScriptAndRun_Click(object sender, EventArgs e)
        {
            try
            {
                if (File.Exists("designer.out.tmp")) File.Delete("designer.out.tmp");
                File.WriteAllLines("designer.out.tmp", ScriptHelper.Script(dx).Split('\n'), Encoding.ASCII);
                new Thread(new ThreadStart(RunScript)).Start();
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
            RefreshToolbar();
        }

        private void btnDrawTriangles_Click(object sender, EventArgs e)
        {
            dx.ShowTriangles = btnDrawTriangles.Checked;
            RefreshToolbar();
        }

        private void btnPreview_Click(object sender, EventArgs e)
        {
            try
            {
                new Thread(new ThreadStart(RunGame)).Start();
            }
            catch (Exception x)
            {
                if (MessageBox.Show(x.Message, x.Source, MessageBoxButtons.OKCancel, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Cancel)
                    Application.Exit();
            }
        }

        void RunGame()
        {
            dx.CreateWorld();
            Sectors.Program.Main(dx.World);
        }

        void RunScript()
        {
            string[] args = ("designer.out.tmp").Split(' ');
            Sectors.Program.Main(args);
        }

        public void RefreshToolbar()
        {
            locked = false;

            btnSelectSector.Checked =
                btnNewSector.Checked =
                btnMoveVertex.Checked =
                btnSelectLine.Checked = false;
            switch (dx.EditMode)
            {
                case SectorsMapMakerControl.EditModes.NewSector:
                    btnNewSector.Checked = true;
                    break;
                case SectorsMapMakerControl.EditModes.SelectEdge:
                    btnSelectLine.Checked = true;
                    break;
                case SectorsMapMakerControl.EditModes.SelectSector:
                    btnSelectSector.Checked = true;
                    break;
                case SectorsMapMakerControl.EditModes.SelectVertex:
                    btnMoveVertex.Checked = true;
                    break;
            }

            btnFillCeiling.Checked =
                btnFillFloor.Checked =
                btnNoFill.Checked =
                btnSolidFill.Checked = false;
            switch (dx.SectorFillMode)
            {
                case SectorsMapMakerControl.SectorFillModes.Ceiling:
                    btnFillCeiling.Checked = true;
                    break;
                case SectorsMapMakerControl.SectorFillModes.Floor:
                    btnFillFloor.Checked = true;
                    break;
                case SectorsMapMakerControl.SectorFillModes.Solid:
                    btnSolidFill.Checked = true;
                    break;
                case SectorsMapMakerControl.SectorFillModes.Wire:
                    btnNoFill.Checked = true;
                    break;
            }

            vertexToolStripMenuItem.Checked = btnMoveVertex.Checked;
            sectorToolStripMenuItem.Checked = btnSelectSector.Checked;
            wallToolStripMenuItem.Checked = btnSelectLine.Checked;
            createToolStripMenuItem.Checked = btnNewSector.Checked;

            wireToolStripMenuItem.Checked = btnNoFill.Checked;
            floorToolStripMenuItem.Checked = btnFillFloor.Checked;
            ceilingToolStripMenuItem.Checked = btnFillCeiling.Checked;
            solidToolStripMenuItem.Checked = btnSolidFill.Checked;
        }

        private void btnWallProperties_Click(object sender, EventArgs e)
        {
            new WallPropertiesForm(dx.Edges[dx.CurrentEdgeIndex].Wall,dx).ShowDialog();
            dx.RefreshListBox();
        }

        private void wallsListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (locked) return;
            dx.EditMode = SectorsMapMakerControl.EditModes.SelectEdge;
            dx.SelectedEdgesIndices = new List<int>();
            foreach (int item in wallsListBox.SelectedIndices)
            {
                dx.SelectedEdgesIndices.Add(item);
            }
            //dx.CurrentEdgeIndex = wallsListBox.SelectedIndex;
            RefreshToolbar();
        }

        private void verticesListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (locked) return;
            dx.EditMode = SectorsMapMakerControl.EditModes.SelectVertex;
            dx.CurrentVertexIndex = verticesListBox.SelectedIndex;
            RefreshToolbar();
        }

        private void btnFillFloor_Click(object sender, EventArgs e)
        {
            dx.SectorFillMode = SectorsMapMakerControl.SectorFillModes.Floor;
            RefreshToolbar();
        }

        private void btnFillCeiling_Click(object sender, EventArgs e)
        {
            dx.SectorFillMode = SectorsMapMakerControl.SectorFillModes.Ceiling;
            RefreshToolbar();
        }

        private void btnNoFill_Click(object sender, EventArgs e)
        {
            dx.SectorFillMode = SectorsMapMakerControl.SectorFillModes.Wire;
            RefreshToolbar();
        }

        private void btnReverseEdge_Click(object sender, EventArgs e)
        {
            //dx.Edges[dx.CurrentEdgeIndex].Reverse();
            dx.ReverseSelected();
            RefreshToolbar();
        }

        private void setCeilingTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UseTextureChooser(TextureChooserModes.Ceiling);
        }

        private void setFloorTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UseTextureChooser(TextureChooserModes.Floor);
        }

        private void setUpperTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UseTextureChooser(TextureChooserModes.Upper);
        }

        private void setLowerTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UseTextureChooser(TextureChooserModes.Lower);
        }

        private void setBackTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UseTextureChooser(TextureChooserModes.Back);
        }

        private void setWallTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UseTextureChooser(TextureChooserModes.Wall);
        }

        enum TextureChooserModes
        {
            Ceiling,
            Floor,
            Upper,
            Lower,
            Back,
            Wall
        }

        void UseTextureChooser(TextureChooserModes mode)
        {
            TextureChooserDialog d = new TextureChooserDialog(dx);
            if (d.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) return ;
            if (mode != TextureChooserModes.Ceiling && mode != TextureChooserModes.Floor) //wall
            {
                foreach (int item in wallsListBox.SelectedIndices)
                {
                    switch (mode)
                    {
                        case TextureChooserModes.Wall:
                            dx.Edges[item].Wall.Texture = d.TextureNameBox.Text.Trim().ToLower();
                            break;
                        case TextureChooserModes.Back:
                            dx.Edges[item].Wall.TextureB = d.TextureNameBox.Text.Trim().ToLower();
                            break;
                        case TextureChooserModes.Upper:
                            dx.Edges[item].Wall.TextureU = d.TextureNameBox.Text.Trim().ToLower();
                            break;
                        case TextureChooserModes.Lower:
                            dx.Edges[item].Wall.TextureL = d.TextureNameBox.Text.Trim().ToLower();
                            break;
                    }
                }
            }
            else
            {
                foreach (int item in sectorsListBox.SelectedIndices)
                {
                    if (mode == TextureChooserModes.Floor)
                        dx.Sectors[item].FloorTexture = d.TextureNameBox.Text.Trim().ToLower();
                    else
                        dx.Sectors[item].CeilingTexture = d.TextureNameBox.Text.Trim().ToLower();
                }
            }
        }

        private void saveWorldToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(dx.FileName))
            {
                saveAsToolStripMenuItem_Click(sender, e);
            }
            else
            {
                dx.Save(dx.FileName);
            }
            Text = AppTitle + " - " + new FileInfo(dx.FileName).Name;
        }

        private void btnSolidFill_Click(object sender, EventArgs e)
        {
            dx.SectorFillMode = SectorsMapMakerControl.SectorFillModes.Solid;
            RefreshToolbar();
        }

        private void snapToGridToolStripMenuItem_Click(object sender, EventArgs e)
        {
            dx.DoSnapToGrid = snapToGridToolStripMenuItem.Checked;
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (locked) return;
            if (e.Node == null) return;
            var key = e.Node.Name;
            switch (key[0])
            {
                case 'p':
                    return;
                case 's':
                    {
                        dx.EditMode = SectorsMapMakerControl.EditModes.SelectSector;
                        var i = int.Parse(key.Substring(1, key.Length - 1));
                        dx.SelectedSectorsIndices = new List<int>() { i };
                        propertyGrid1.SelectedObject = dx.Sectors[i];
                    }
                    break;
                case 'e':
                    {
                        dx.EditMode = SectorsMapMakerControl.EditModes.SelectEdge;
                        var i = int.Parse(key.Substring(1, key.Length - 1));
                        dx.SelectedEdgesIndices = new List<int>() { i };
                        propertyGrid1.SelectedObject = dx.Edges[i].Wall;
                    }
                    break;
                case 'v':
                    dx.EditMode = SectorsMapMakerControl.EditModes.SelectVertex;
                    dx.CurrentVertexIndex = int.Parse(key.Substring(1, key.Length - 1));
                    break;
            }
            RefreshToolbar();
        }
    }
}
